#include "preHeader.h"
#include "DBPHelper.h"
#include "DBPSession.h"

RPCError DBPHelper::RPCBlockInvoke(RPCActor* actor, const INetPacket& pck,
	const std::function<void(INetStream&)>& cb,
	const std::function<RPCError()>& updater)
{
	bool isEOF = false;
	RPCError errCode = RPCErrorNone;
	std::condition_variable_any cv;
	actor->RPCInvoke(pck, [&](INetStream& pck, int32 err, bool eof) {
		if (err != RPCErrorNone) {
			errCode = (RPCError)err;
			cv.notify_one();
			return;
		}
		TRY_BEGIN {
			cb(pck);
		} TRY_END
		CATCH_BEGIN(...) {
			errCode = RPCErrorInterrupt;
			cv.notify_one();
			return;
		} CATCH_END
		if (eof) {
			isEOF = eof;
			cv.notify_one();
			return;
		}
	});
	fakelock lock;
	const std::chrono::milliseconds duration(100);
	while (cv.wait_for(lock, duration), true) {
		if (isEOF || errCode != RPCErrorNone ||
			(updater && (errCode = updater()) != RPCErrorNone)) {
			break;
		}
	}
	return errCode;
}
